package com.cskaoyan.service.wx.impl;

import com.cskaoyan.bean.bo.WxAuthRegisterBo;
import com.cskaoyan.bean.common.BaseRespVo;
import com.cskaoyan.bean.po.*;
import com.cskaoyan.bean.vo.WxAuthRegisterVo;
import com.cskaoyan.bean.vo.WxAuthResetBo;
import com.cskaoyan.bean.vo.wx.WxAuthLoginVo;
import com.cskaoyan.config.AliyunComponent;
import com.cskaoyan.config.realm.MarketToken;
import com.cskaoyan.controller.system.aspect.HelloAspect;
import com.cskaoyan.mapper.MarketUserMapper;
import com.cskaoyan.service.wx.WxAuthService;
import com.cskaoyan.util.Constant;
import com.cskaoyan.util.RedisUtil;
import com.cskaoyan.util.SymmetricEncryption;
import io.lettuce.core.RedisException;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author jzp
 * @since 2022/11/22 13:52
 */
@Service
@Transactional
public class WxAuthServiceImpl implements WxAuthService {
    @Autowired
    AliyunComponent aliyunComponent;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public BaseRespVo login(String username, String password) {
        //在这里要执行登录，Subject.login
        // → Subject只能作为局部变量，不能作为全局变量
        Subject subject = SecurityUtils.getSubject();
        // 执行登录（认证）
        MarketToken authenticationToken = new MarketToken(username, password, "wx");
        try {
            subject.login(authenticationToken);
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }
        if (subject.isAuthenticated()) {
            Session session = subject.getSession();

            MarketUser primaryPrincipal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();

            WxAuthLoginVo wxAuthLoginVo = new WxAuthLoginVo();
            WxAuthLoginVo.UserInfoDTO userInfo = new WxAuthLoginVo.UserInfoDTO();

            userInfo.setAvatarUrl(primaryPrincipal.getAvatar());
            userInfo.setNickName(primaryPrincipal.getNickname());

            wxAuthLoginVo.setUserInfo(userInfo);

            wxAuthLoginVo.setToken((String) session.getId());
            return BaseRespVo.ok(wxAuthLoginVo);
        }


        BaseRespVo<Object> baseRespVo = new BaseRespVo<>();
        baseRespVo.setErrno(605);
        baseRespVo.setErrmsg("用户帐号或密码不正确");
        return baseRespVo;
    }


    @Override
    public boolean regCaptcha(String mobile) {
        if (!mobile.matches(Constant.CHECK_MOBILE_PHONE)) {
            System.out.println("验证错误！！！");
            return false;
        }
        int code = (int) ((Math.random() * 9 + 1) * 100000);
        // int code = 1001;
        aliyunComponent.sendMsg(mobile, Integer.toString(code));
        redisUtil.setString(mobile, String.valueOf(code), 5, TimeUnit.MINUTES);
        return true;
    }

    @Autowired
    MarketUserMapper marketUserMapper;


    @Override
    public WxAuthRegisterVo register(WxAuthRegisterBo wxAuthRegisterBo, HttpServletRequest request) {
        String code = wxAuthRegisterBo.getCode();
        String mobile = wxAuthRegisterBo.getMobile();
        String cacheCode = redisUtil.getString(mobile);
        if (cacheCode == null || !cacheCode.equals(code)) {
            return null;
        }
        // 从数据库从查看 username 和 手机号 是否已经注册了
        MarketUserExample example = new MarketUserExample();
        example.createCriteria().andUsernameEqualTo(wxAuthRegisterBo.getUsername());
        List<MarketUser> userListUsername = marketUserMapper.selectByExample(example);
        if (userListUsername.size() > 0) {
            WxAuthRegisterVo wxAuthRegisterVo = new WxAuthRegisterVo();
            wxAuthRegisterVo.setToken("用户名重复");
            return wxAuthRegisterVo;
        }
        example.clear();
        example.createCriteria().andMobileEqualTo(wxAuthRegisterBo.getMobile());
        List<MarketUser> userListMobile = marketUserMapper.selectByExample(example);
        if (userListMobile.size() > 0) {
            WxAuthRegisterVo wxAuthRegisterVo = new WxAuthRegisterVo();
            wxAuthRegisterVo.setToken("手机号已经注册");
            return wxAuthRegisterVo;
        }
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        // 插入数据
        MarketUser marketUser = new MarketUser();
        marketUser.setUsername(wxAuthRegisterBo.getUsername());

        // 数据库存储的密码应该是加密的
        String encryption = SymmetricEncryption.encryption(wxAuthRegisterBo.getPassword());
        marketUser.setPassword(encryption);
        marketUser.setGender((byte) 0);

        marketUser.setUserLevel((byte) 0);
        marketUser.setNickname(wxAuthRegisterBo.getUsername());
        marketUser.setMobile(mobile);
        marketUser.setAvatar(Constant.DOMAIN + "picture/img/mr.png");
        marketUser.setStatus((byte) 0);
        try {
            // 设置ip
            marketUser.setLastLoginIp(HelloAspect.getIP(request));
        } catch (Exception e) {
            e.printStackTrace();
        }
        Date date = new Date();
        marketUser.setLastLoginTime(date);
        marketUser.setAddTime(date);
        marketUser.setWeixinOpenid("微信登录openid");
        marketUser.setSessionKey((String) session.getId());

        int num = marketUserMapper.insert(marketUser);

        // 登录认证的密码应该是明文
        MarketToken authenticationToken = new MarketToken(marketUser.getUsername(), wxAuthRegisterBo.getPassword(), "wx");
        try {
            subject.login(authenticationToken);
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }


        WxAuthRegisterVo wxAuthRegisterVo = new WxAuthRegisterVo();
        WxAuthRegisterVo.UserInfoDTO userInfoDTO = new WxAuthRegisterVo.UserInfoDTO();
        userInfoDTO.setAvatarUrl(marketUser.getAvatar());
        userInfoDTO.setNickName(marketUser.getNickname());

        wxAuthRegisterVo.setUserInfo(userInfoDTO);
        wxAuthRegisterVo.setToken((String) session.getId());
        return wxAuthRegisterVo;
    }

    @Override
    public Integer reset(WxAuthResetBo wxAuthRegisterBo) {
        MarketUserExample example = new MarketUserExample();
        example.createCriteria().andMobileEqualTo(wxAuthRegisterBo.getMobile());
        List<MarketUser> marketUserList = marketUserMapper.selectByExample(example);
        if (marketUserList.size() == 0) {
            // 说明手机未注册
            return null;
        }
        System.out.println(wxAuthRegisterBo.getCode());
        System.out.println(redisUtil.getString(wxAuthRegisterBo.getMobile()));
        if (!wxAuthRegisterBo.getCode().equals(redisUtil.getString(wxAuthRegisterBo.getMobile()))) {
            return 0;
        }
        MarketUser marketUser = marketUserList.get(0);
        String clear = wxAuthRegisterBo.getPassword();
        String encryption = SymmetricEncryption.encryption(clear);
        marketUser.setPassword(encryption);
        example.clear();
        marketUserMapper.updateByPrimaryKeySelective(marketUser);
        return 1;
    }
}
